package com.logger;

import org.aspectj.lang.ProceedingJoinPoint;

/**
 * 用于记录日志的工具类，它里面提供了公共的代码
 */
public class Logger {


    /**
     * 前置通知
     */
    private void beforePrintLog(){
        System.out.println("Logger类中的printLog方法开始记录日志了...............beforePrintLog");
    }

    /**
     * 后置通知
     */
    private void afterPrintLog(){
        System.out.println("Logger类中的printLog方法开始记录日志了...............afterPrintLog");
    }

    /**
     * 异常通知
     */
    private void afterThrowPintLog(){
        System.out.println("Logger类中的printLog方法开始记录日志了...............afterThrowPintLog");
    }

    /**
     * 最终通知
     */
    private void finallyPrintLog(){
        System.out.println("Logger类中的printLog方法开始记录日志了..............finallyPrintLog.");
    }
    /**
     * 环绕通知
     *问题：
     *     当我们配置了环绕通知，切入点方法没有执行，而通知方法执行了。
     * 分析：
     *     通过对比动态代理中的环绕通知代码，发现动态代理的环绕通知有明确的切入点方法调用，而我们的代码中没有。
     * 解决：
     *     Spring框架为我们提供了一个接口，ProceedingJoinPoint. 还借口有一个方法proceed()，此方法就相当于明确调用切入点方法。
     *     该接口可以作为环绕通知的方法参数，在程序执行时，spring框架会为我们提供该接口的实现类供我们使用。
     * spring中的环绕通知：
     *     他是spring框架为我们提供的一种可以在代码中手动控制增强法法何时执行的方式。
     *
     */
    private Object aroundPrintLog(ProceedingJoinPoint point){
        Object reValue = null;
        try{
            System.out.println("前置通知");
            Object[] args = point.getArgs();
            reValue = point.proceed(args);
            System.out.println("后置通知");
        }catch (Throwable t){
            System.out.println("异常通知");
            throw  new RuntimeException(t);
        }finally {
            System.out.println("最终通知");
        }
        return reValue;
    }

}
